<?php

namespace App\Controller\Admin;

use App\Agent\RedisQueueAgent;
use App\Constants\ErrorCode;
use App\Constants\GameRole;
use App\Constants\QmGame;
use App\Constants\RedisKey;
use App\Controller\InsideService\GameUserInside;
use App\Controller\InsideService\PaySenderInside;
use App\Middleware\AdminMiddleware;
use App\Model\QmGameList;
use App\Model\QmGameOrder;
use App\Service\ExcelService;
use App\Service\MiMasterService;
use App\Service\QmGameService;
use App\Service\TiktokPayService;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Guzzle\ClientFactory;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;

#[Controller(prefix: '/admin/Order'), Middleware(AdminMiddleware::class)]
class OrderController extends BaseController {

    /**
     * @Inject
     * @var ClientFactory
     */
    protected ClientFactory $clientFactory;

    /**
     * 描述: 获取订单列表
     * 日期: 2023/3/21 10:58
     * @return array
     * @throws ContainerExceptionInterface
     * @throws GuzzleException
     * @throws NotFoundExceptionInterface
     * @author: cinder
     */
    #[GetMapping(path: 'getOrderInfo')]
    public function getOrderInfo(): array {
        $userDataArr = $this->uInfo();
        $limit = $this->request->query('size', config('apiadmin.admin_list_default'));
        $game_hash = $this->request->query('game_hash', '');
        $status = $this->request->query('status', -1);
        $openid = $this->request->query('openid', '');
        $date = $this->request->query('date', '');
        $order_num = $this->request->query('order_num', '');
        $platform = $this->request->query('platform', '');

        $userInfo = [];
        $listObj = QmGameOrder::query();
        if ($game_hash) {
            $listObj = $listObj->where('game_hash', $game_hash);
            if ($openid) {
                $listObj = $listObj->where('openid', $openid);
                $userInfoApi = (new GameUserInside())->setCode($userDataArr['connection_code'])
                    ->getUserInfoByOpenid($game_hash, $openid);
                if ($userInfoApi['data'] && $userInfoApi['data']['list']) {
                    $userInfo = $userInfoApi['data']['list'];
                    $userInfo['total_money'] = QmGameOrder::query()
                        ->where('game_hash', $game_hash)
                        ->where('openid', $openid)
                        ->whereIn('status', [1, 3, 4])
                        ->sum('money');
                }
            }
        }
        if ($status >= 0) {
            $listObj = $listObj->where('status', $status);
        }
        if ($order_num) {
            $listObj = $listObj->where('order_num', $order_num);
        }
        if ($platform) {
            $listObj = $listObj->where('platform_from', $platform);
        }
        if (is_array($date) && !empty($date[0])) {
            $listObj = $listObj->whereBetween('create_date', $date);
        }
        $listObj = $listObj->orderByDesc('created_at')->paginate((int)$limit);

        if ($userInfo && $listObj->total()) {
            $orderDetail = $listObj->items()[0];

            $game_info = QmGameService::getGameInfo($orderDetail['game_hash']);
            if ($orderDetail['platform'] == 2) {
                if ($game_info['platform'] == 2) {
                    $userInfo['balance'] = (new TiktokPayService())->getBalance($orderDetail)['balance'];
                } else if ($game_info['platform'] == 1) {
                    $userInfo['balance'] = (new MiMasterService())->getBalance($orderDetail)['balance'];
                }
            } else {
                $userInfo['balance'] = 0;
            }
        }

        $return = [
            'list'     => $listObj->items(),
            'count'    => $listObj->total(),
            'userInfo' => $userInfo
        ];
        return $this->buildSuccess($return);
    }

    /**
     * 描述: 导出订单
     * 日期: 2023/3/21 10:58
     * @return array|ResponseInterface
     * @author: cinder
     */
    #[GetMapping(path: 'export')]
    public function export(): array|ResponseInterface {
        set_time_limit(0);
        ini_set('memory_limit', '5048M');
        $game_hash = $this->request->query('game_hash', '');
        $status = $this->request->query('status', -1);
        $date = $this->request->query('date', '');
        $order_num = $this->request->query('order_num', '');
        $platform = $this->request->query('platform', '');
        $openid = $this->request->query('openid', '');

        $listObj = QmGameOrder::query();
        if ($game_hash) {
            $listObj = $listObj->where('game_hash', $game_hash);
        }
        if ($status >= 0) {
            $listObj = $listObj->where('status', $status);
        }
        if ($openid) {
            $listObj = $listObj->where('openid', $openid);
        }
        if ($order_num) {
            $listObj = $listObj->where('order_num', $order_num);
        }
        if ($platform) {
            $listObj = $listObj->where('platform_from', $platform);
        }
        if (is_array($date) && !empty($date[0])) {
            $listObj = $listObj->whereBetween('create_date', $date);
        }
        $listObj = $listObj->orderByDesc('created_at');

        //先判断数量
        if ($listObj->count() <= 0) {
            return $this->buildFailed(ErrorCode::INVALID, '1'); //返回标识 前端返回提示
        }

        if ($listObj->count() > 1000) {
            return $this->buildFailed(ErrorCode::INVALID, '11'); //返回标识 前端返回提示
        }

        $list = $listObj->get()->toArray();
        $fileName = '订单-' . date('YmdHis');
        $title = [
            'ID',
            'openid',
            '角色',
            '订单编号',
            '平台',
            '订单金额',
            '订单状态',
            '所属游戏',
            '交易时间',
        ];
        //表体数据

        $data = [];
        foreach ($list as $value) {
            //平台
            $platform = $value['platform'] == 1 ? 'IOS' : '安卓';
            //订单状态
            $data[] = [
                $value['id'],
                $value['openid'],
                QmGame::ROLE_LIST[$value['hero_id']] ?? '',
                $value['order_num'],
                $platform,
                $value['money'],
                QmGameOrder::STATUS_LIST[$value['status']],
                QmGame::GAME_LIST[$value['game_hash']],
                $value['created_at'],
            ];
        }
        $exportService = new ExcelService();

        //保存临时文件在从浏览器自动下载到本地
        return $exportService->setHeader($title)->addData($data)->saveToBrowserByTmp($fileName);
    }

    /**
     * 描述: 计算订单金额
     * 日期: 2023/3/7 16:59
     * @return array[]
     * @author: cinder
     */
    #[GetMapping(path: 'getOrderMoney')]
    public function getOrderMoney() {
        $game_hash = $this->request->query('game_hash', '');
        $date = $this->request->query('date', '');
        $platform = $this->request->query('platform', '');

        $totalObj = QmGameOrder::query();
        $rangeObj = QmGameOrder::query();
        if (is_array($date) && !empty($date[0])) {
            $rangeObj = $rangeObj->whereBetween('create_date', $date);
        }
        $todayObj = QmGameOrder::query()->where('create_date', date('Y-m-d'));
        if ($game_hash) {
            $totalObj->where('game_hash', $game_hash);
            $todayObj->where('game_hash', $game_hash);
            $rangeObj->where('game_hash', $game_hash);
        }
        if ($platform) {
            $totalObj->where('platform_from', $platform);
            $todayObj->where('platform_from', $platform);
            $rangeObj->where('platform_from', $platform);
        }
        $total = [
            'sum' => round($totalObj->sum('money'), 2),
            'pay' => round($totalObj->whereIn('status', [1, 3, 4])->sum('money'), 2)
        ];
        $today = [
            'sum' => round($todayObj->sum('money'), 2),
            'pay' => round($todayObj->whereIn('status', [1, 3, 4])->sum('money'), 2)
        ];
        $range = [
            'sum' => round($rangeObj->sum('money'), 2),
            'pay' => round($rangeObj->whereIn('status', [1, 3, 4])->sum('money'), 2)
        ];

        $return = [
            'total' => $total,
            'today' => $today,
            'range' => $range
        ];
        return $this->buildSuccess($return);
    }


    /**
     * 订单补单
     * @return array
     * @throws GuzzleException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[GetMapping(path: 'backOrder')]
    public function backOrder(): array {
        $orderNum = $this->request->query('order_num', '');
        if ($orderNum) {
            $orderInfo = QmGameOrder::query()->where('order_num', $orderNum)->first();
            if ($orderInfo) {
                if ($orderInfo->platform == 2) {
                    $game_info = QmGameService::getGameInfo($orderInfo->game_hash);
                    if ($game_info['platform'] == 2) {
                        $contentBalance = (new TiktokPayService())->getBalance($orderInfo->toArray());
                    } else if ($game_info['platform'] == 1) {
                        $contentBalance = (new MiMasterService())->getBalance($orderInfo->toArray());
                    }
                    if (isset($contentBalance['balance']) && $contentBalance['balance']) {
                        // 请求平台扣款
                        if ($game_info['platform'] == 2) {
                            $content = (new TiktokPayService())->doPay($orderInfo->toArray());
                        } else if ($game_info['platform'] == 1) {
                            $content = (new MiMasterService())->doPay($orderInfo->toArray());
                        }
                        if (isset($content) && $content['errcode'] == 0) {
                            (new PaySenderInside())->sendReward($orderInfo->toArray());
                            $orderInfo->status = 1;
                            $orderInfo->save();
                            return $this->buildSuccess();
                        } else {
                            $orderInfo->status = 2;
                            $orderInfo->error_msg = json_encode($content);
                            $orderInfo->save();

                            return $this->buildFailed(ErrorCode::CURL_ERROR, '支付失败');
                        }
                    } else {
                        return $this->buildFailed(ErrorCode::INVALID, '米大师余额不足，请核实！');
                    }
                } else {
                    $client = $this->clientFactory->create(['verify' => false]);
                    $url = "https://darknight.games/api/wx/wx_game/getOrderState";
                    $response = $client->post($url, [
                        'json' => [
                            'orderId' => $orderNum
                        ]
                    ]);
                    $originContent = $response->getBody()->getContents();
                    $content = json_decode($originContent, true);
                    if ($content['code'] != 200 || $content['state'] != 0) {
                        $orderInfo->status = 2;
                        $orderInfo->error_msg = $originContent;
                        $orderInfo->save();

                        return $this->buildFailed(ErrorCode::CURL_ERROR, '支付失败');
                    }
                    (new PaySenderInside())->sendReward($orderInfo->toArray());

                    $orderInfo->status = 1;
                    $orderInfo->save();

                    return $this->buildSuccess();
                }
            } else {
                return $this->buildFailed(ErrorCode::NOT_EXISTS, '订单不存在');
            }
        } else {
            return $this->buildFailed(ErrorCode::PARAM_INVALID, '缺少必要参数');
        }
    }

    /**
     * 订单补单
     * @return array
     * @throws GuzzleException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[GetMapping(path: 'backOrderForDeveloper')]
    public function backOrderForDeveloper(): array {
        $orderNum = $this->request->query('order_num', '');
        $op = $this->request->query('op', 0);

        if (!$orderNum) return $this->buildFailed(ErrorCode::NOT_EXISTS, '传订单号');
        $orderInfo = QmGameOrder::query()->where('order_num', $orderNum)->first()->toArray();
        if (!$orderInfo) return $this->buildFailed(ErrorCode::NOT_EXISTS, '订单未找到');
        //处理操作
        if ($op > 0) {
            (new PaySenderInside())->reSendReward($orderInfo, $op);
            return $this->buildSuccess();
        }
        //查询用户数据 含充值总金额  活动累计充值 点券获得记录 当前角色的等级投资情况
        $data = (new PaySenderInside())->sendData($orderInfo);
        //账号查询累充订单金额
        if (isset($data['festival']) and $data['festival']['fid'] > 0) {
            $data['festivalTimePayTotal'] = $this->getFestivalTimePayTotal($orderInfo);
        }
        //点券购买 查询当前订单时间前后1小时内的所有安卓订单 不区分订单状态
        if ($data['shop_type'] == 4) {
            $date = [
                date("Y-m-d H:i:s", strtotime($orderInfo['created_at']) - 3600), date("Y-m-d H:i:s", strtotime($orderInfo['created_at']) + 3600)
            ];
            $orderList = QmGameOrder::query()->where('game_hash', $orderInfo['game_hash'])
                ->where('openid', $orderInfo['openid'])
                ->where('uid', $orderInfo['uid'])
                ->where('role_id', $orderInfo['role_id'])
                ->where('platform', 2)
                ->whereBetween('created_at', $date)
                ->select('id', 'order_num', 'goods_id', 'money', 'number', 'status', 'check', 'error_msg', 'version', 'created_at');
            $data['orderList'] = $orderList;
        }
        $data['tips'] = ["op参数：1:补充充值次数(每次+1)，2：补充充值总金额(+当前订单金额)，3：补充活动累计(当前有活动进行中才可以执行成功)，4：补充点券或等级投资"];
        return $this->buildSuccess($data);
    }

    private function getFestivalTimePayTotal($orderInfo) {
        $date = ["2022-03-07 11:00:00", date("Y-m-d H:i:s")];
        return QmGameOrder::query()
            ->where('game_hash', $orderInfo['game_hash'])
            ->where('openid', $orderInfo['openid'])
            ->where('uid', $orderInfo['uid'])
            ->where("status", "=", 1)
            ->whereBetween('created_at', $date)
            ->sum("money");
    }
}